// // ================================================================================================================================================
//     // ============================================================================================================================================
//     //
//     //
//     //
//     //
//     // UV模块
//     //
//     //
//     //
//     //
//     // ============================================================================================================================================
//     /*
//         变换过程优先级:
//             1.模型UV/屏幕UV
//             2.矩阵变换(一次性的，旋转，缩放（翻转），偏移)
           
//             5.clamp限定0-1的UV
//              3.极坐标
             
//             4.动态偏移UV
//             6.序列帧 (如果有的话)
//             7.扰动UV
//     */
// #ifndef UNITY_SHADER_DT_UV_UTIL_INCLUDED  
// #define UNITY_SHADER_DT_UV_UTIL_INCLUDED
//     // ==================================================================
//     // 引用
//     // ==================================================================
//     //  #include "XXXXXX.hlsl"  

//     // ============================================================================================================================================
//     //
//     //
//     //
//     //
//     // 变换的矩阵
//     //
//     //
//     //
//     //
//     // ============================================================================================================================================
        
//         // ==================================================================
//         // 常量
//         // ==================================================================
//             const float4x4 _DTDefMatr = float4x4
//             (
//                 1.0, 0.0, 0.0, 0.0,
//                 0.0, 1.0, 0.0, 0.0,
//                 0.0, 0.0, 1.0, 0.0,
//                 0.0, 0.0, 0.0, 1.0
//             );

//             const float4x4 _DThalfMatr = float4x4
//             (
//                 0.5, 0.0, 0.0, 0.5,
//                 0.0, 0.5, 0.0, 0.5,
//                 0.0, 0.0, 1.0, 0.0,
//                 0.0, 0.0, 0.0, 1.0
//             );        
//             const float4x4 _DTCenterMatr = float4x4
//             (
//                 2.0, 0.0, 0.0, -1.0,
//                 0.0, 2.0, 0.0, -1.0,
//                 0.0, 0.0, 1.0,  0.0,
//                 0.0, 0.0, 0.0,  1.0
//             );
//         // ==================================================================
//         // 函数
//         // ==================================================================            
//             float4x4 RotUVMatrix(float angle) // normalizedValue 0-360
//             {
//                 float normalizedValue = angle / 360.0; // 归一化角度值到 0 到 1
//                 float radians = normalizedValue * 3.14159265359 * 2.0; // 角度转换为弧度
//                 float cosv = cos(radians); // 计算余弦值
//                 float sinv = sin(radians); // 计算正弦值
//                 return float4x4
//                 (
//                     cosv, -sinv, 0.0, 0.0,
//                     sinv,  cosv, 0.0, 0.0,
//                     0.0,   0.0, 1.0, 0.0,
//                     0.0,   0.0, 0.0, 1.0
//                 );
//             }
//             float4x4 TilingAndOffsetUVMatrix(float4 _TilingOffset)
//             {
//                 return float4x4
//                 (
//                     _TilingOffset.x, 0.0f, 0.0f, -1.0 * _TilingOffset.z,
//                     0.0f, _TilingOffset.y, 0.0f, -1.0 * _TilingOffset.w,
//                     0.0f, 0.0f, 1.0f, 0.0f,
//                     0.0f, 0.0f, 0.0f, 1.0f
//                 );
//             }
//             //计算UV矩阵
//             #if defined(DT_USE_OPTIMIZE)
//                 //AI帮助合并了矩阵的计算中的常量、重复计算等。所以这个结果只能使用无法再做顺序改动
//                 float4x4 CalcUVMatrix(float2 _Tiling, float2 Offset, float angle)
//                 {
//                     // 直接计算合并后的矩阵元素，避免矩阵乘法
//                     float normalizedValue = angle / 360.0;
//                     float radians = normalizedValue * 3.14159265359 * 2.0;
//                     float cosv = cos(radians);
//                     float sinv = sin(radians);
                    
//                     // 一次性计算所有变换的组合效果                    
//                     // 预计算重复使用的表达式
//                     float2 cos_s = cosv * _Tiling;
//                     float2 sin_s = sinv * _Tiling;                    
//                     // 预计算偏移相关项 
//                     float2 t2 = 2.0 * Offset;

//                     float term1 = -cos_s.x + sin_s.y - t2.x * cos_s.x + t2.y * sin_s.y;
//                     float term2 = -sin_s.x - cos_s.y + t2.x * sin_s.x + t2.y * cos_s.y;
                    
//                     // 合并所有矩阵变换：_DThalfMatr * (rotMatr * tranMatr) * _DTCenterMatr
//                     // 直接计算最终的矩阵元素
//                     return float4x4(
//                         cos_s.x, -sin_s.y, 0.0, 0.5 * term1 + 0.5,
//                         sin_s.x, cos_s.y,  0.0, 0.5 * term2 + 0.5,
//                         0.0, 0.0, 1.0, 0.0,
//                         0.0, 0.0, 0.0, 1.0
//                     );
//                 }
//             #else
//                 float4x4 CalcUVMatrix(float2 _Tiling,float2 Offset,float angle)
//                 {
//                     float4x4 rotMatr =  RotUVMatrix(angle);
//                     float4x4 tranMatr = TilingAndOffsetUVMatrix(float4(_Tiling, Offset));
//                     float4x4 finalMatr = mul(rotMatr, tranMatr);
//                     return mul(_DThalfMatr, mul(finalMatr, _DTCenterMatr));
//                 }
//             #endif
//             // 极坐标计算
//             float2 CalcPolarCoord(float2 _uv, float2 Center)
//             {
//                 const float2 delta = _uv - Center;
//                 const float radius = length(delta) * 2.0;
//                 const float angle = atan2(delta.x, delta.y) * 0.15915494309f;
//                 // 不同以往的改动  重要改动
//                 return float2(radius,angle);
//             }
//             // 计算屏幕坐标
//             float3 CalcSceneCoord(float4 positionHCS)
//             {
//                 const float4 tmp = ComputeScreenPos(positionHCS);            
//                 return float3(tmp.xy / DT_SAFE_VALUE(tmp.w),tmp.w);
//             }

            
//         // ==================================================================
//         // 结构体
//         // ================================================================== 
//             struct MatrixResult
//             {
//                 float2 Tiling;
//                 float2 Offset;
//                 float Angle;
//                 float2 CustomOffset; 
//                 float2 IsWorld;
//             };
//         // ==================================================================
//         // 初始化
//         // ================================================================== 
//             MatrixResult InitMatrixData(float4 _TilingOffset, float _Angle,float2 _CustomOffset,float2 _isWorld)
//             {
//                 MatrixResult m = (MatrixResult)0;
//                 m.Tiling = _TilingOffset.xy;
//                 m.Offset = _TilingOffset.zw * float2(1.0, -1.0);
//                 m.CustomOffset =  _CustomOffset;
//                 m.Angle = _Angle; 
//                 m.IsWorld = _isWorld;
//                 return m;
//             }
//         // ==================================================================
//         // 调用 & 计算  
//         // ==================================================================    
//             float2 AppendUVMatrix(float4 _uv, MatrixResult _Result, bool _IsSceneUV, bool _IsPolar, bool _IsClampX, bool _IsClampY)
//             {
//                 //模型UV/屏幕UV
//                 float2 uv = _IsSceneUV ? _uv.zw : _uv.xy;
//                 uv = frac(uv + _Result.CustomOffset * _Result.IsWorld); 
//                 //矩阵变换
//                 float4x4 uvMatrix = CalcUVMatrix(_Result.Tiling, _Result.Offset, _Result.Angle);
//                 uv = frac(mul(uvMatrix, float4(uv, 1.0, 1.0)).xy);
//                 //极坐标
//                 uv = _IsPolar ? CalcPolarCoord(uv, float2(0.5, 0.5)) : uv;
//                 uv = frac(uv + _Result.CustomOffset * (1.0 - _Result.IsWorld)); 
                
//                 //clamp
//                 uv.x = _IsClampX ? clamp(uv.x,0.0,1.0) : uv.x;
//                 uv.y = _IsClampY ? clamp(uv.y,0.0,1.0) : uv.y;
//                 return uv;
//             }
//     // ============================================================================================================================================
//     //
//     //
//     //
//     //
//     // 扰动模块
//     //
//     //
//     //
//     //
//     // ============================================================================================================================================
//         // ==================================================================
//         // 结构体
//         // ================================================================== 
//             struct DistortResult
//             { 
//                 float InputData; //从贴图输入的值 
//                 float2 Factor; //扰动的控制值
//             };
//         // ==================================================================
//         // 初始化
//         // ================================================================== 
//             DistortResult InitDistortResult(float _InputData, float2 _Factor)
//             {
//                 DistortResult d = (DistortResult)0;
//                 d.InputData = _InputData;
//                 d.Factor = _Factor * float2(-1.0, 1.0);
//                 return d;
//             }
//         // ==================================================================
//         // 调用 & 计算
//         // ==================================================================
//             //应用于 float
//             void AppendDistortResultV1(DistortResult _Result,inout float _Value)
//             {  
//                 _Value = _Value * max( 1.0 , _Result.Factor.x * _Result.InputData); 
//             }
//             //应用于 float2
//             void AppendDistortResultV2(DistortResult _Result,inout float2 _Value)
//             {  
//                 _Value = _Value + _Value * _Result.Factor * _Result.InputData;
//             }
//             //应用于 UV
//             void AppendDistortResultUV(inout float2 _Value, DistortResult _Result)
//             { 
//                 _Value = _Value * 2.0 - 1.0;
//                 _Value = _Value + _Value * _Result.Factor * _Result.InputData;
//                 _Value = _Value * 0.5 + 0.5;  
//             }
//     // ============================================================================================================================================
//     //
//     //
//     //
//     //
//     // 序列帧模块
//     //
//     //
//     //
//     //
//     // ============================================================================================================================================
//         // ==================================================================
//         // 结构体
//         // ================================================================== 
//             struct DTFrameResult
//             {
//                 int IsOn; //是否开启 
//                 float I_Value; //时间值

//                 int GridX; //切片X
//                 int GridY; //切片Y 
//             };

//             void SafeFrameResult(inout DTFrameResult d)
//             {
//                 d.GridX = max(d.GridX, 1); //切片X
//                 d.GridY = max(d.GridY, 1); //切片Y
//             }
//         // ==================================================================
//         // 初始化
//         // ================================================================== 
//             DTFrameResult InitFrameResult(int _FrameGridX, int _FrameGridY, float _FrameTime)
//             {
//                 DTFrameResult d = (DTFrameResult)0;
//                 d.IsOn = (_FrameGridX + _FrameGridY) ; //是否开启
//                 d.I_Value = _FrameTime; //时间值
//                 d.GridX = _FrameGridX; //切片X
//                 d.GridY = _FrameGridY; //切片Y
//                 return d;
//             }
//         // ==================================================================
//         // 调用 & 计算
//         // ================================================================== 
//             void AppendFrameResult(inout float2 _UV, DTFrameResult d)
//             {
//                 if(d.IsOn > 0.5)
//                 {
//                     SafeFrameResult(d);
//                     float time = floor(d.I_Value);
//                     float row = floor(time / d.GridX);
//                     float column = time - row * d.GridX; 
//                     float2 tiledUV = frac(_UV);
//                     tiledUV.x = tiledUV.x / d.GridX + column / d.GridX;
//                     tiledUV.y = tiledUV.y / d.GridY + (d.GridY - 1.0 - row) / d.GridY;
//                     _UV = tiledUV;
//                 }
//             }
//     // ======================================================================
// #endif //UNITY_SHADER_DT_UV_UTIL_INCLUDED